

(function($){

	/**
	 * <P> DataSource is a collection of data, that user can get part or all of them, 
	 * and step in them to get every piece of it.</P>
	 * 
	 * <P>The data can come from Array or Ajax. DataSource just define an interface, 
	 * the class of DataSourceArray and DataSourceAjax will do the real things.</P>
	 *
	 * <P> DataSource can be connected with a widget to do a paged view of the data
	 * </P>
	 *
	 * @namespace widget
	 * @class DataSource
	 *
	 */
	DataSource = function() {
	}

	/**
	 * DataSourceArray is a DataSource based on an array.
	 * @class DataSourceArray
	 * @param {Array} arr The real source of data
	 */
	DataSourceArray = G.GClass('Widget', 'DataSourceArray', G.Base.EventListener);
	DataSourceArray.prototype.__init = function(arr) {
		this.__Base__EventListener__init();
		this.data = arr;
		this.pageStart = 0;
		this.current = 0;	// Current record in page.
	}

	/**
	 * Get a page of data. this function will fire the 'ondataready' event.
	 *
	 * @method get_data
	 * @param offset {integer} from where the page begin
	 * @param len {integer} the size of page, the lenght of data returned will 
	 * not greater than the page size.
	 *
	 */
	DataSourceArray.prototype.get_data = function(offset, len) 
	{
		this.pageStart = offset;
		var i = this.data.length - offset;
		if (i > len)	i = len;
		this.pageLen = i;

		// Reset pointer to start of the page.
		this.current = 0;	

		this.fire("ondataready", {'offset':offset, 'len': i});
	}

	DataSourceArray.prototype.get_page_len = function()
	{
		return this.pageLen;
	}


	/**
	 * Get data length in total. This function will fire "ontotalchanged" event.
	 *
	 * @mehod get_total
	 */
	DataSourceArray.prototype.get_total = function()
	{
		this.fire("ontotalchanged", this.data.length);
	}
	/**
	 * Get next piece of data in current page.
	 *
	 * @method step_in_page
	 * @return {} the data or null if no more data in current page
	 */
	DataSourceArray.prototype.step_in_page = function() 
	{
		var ret = null;
		if (this.current < this.pageLen) {
			ret = this.data[this.current + this.pageStart];
			this.current += 1;
		}
		return ret;
	}

	DataSourceArray.prototype.seek_in_page = function(offset)
	{
		if (offset < this.pageLen) {
			this.current = offset;
		}
	}


	DataSourceArray.prototype.read = function(offset) 
	{
		if (offset < this.pageLen) {
			return this.data[this.pageStart + offset];
		}
		return null;
	}

	DataSourceArray.prototype.total = function()
	{
		return this.data.length;
	}

})();
